package com.bsoft.gol.hcs.visitrecord.dao;

import com.google.common.collect.Lists;
import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import com.bsoft.gol.hcs.enumcase.FollowTypeEnum;
import com.bsoft.gol.hcs.enumcase.RuleConditionTypeEnum;
import com.bsoft.gol.hcs.his.bean.request.InHospitalpatientListQueryRequest;
import com.bsoft.gol.hcs.his.bean.response.InHospitalPatientResponse;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.transform.Transformers;
import org.springframework.beans.BeanUtils;
import com.bsoft.gol.hcs.specialist.bean.request.GroupChronicRecordQo;
import com.bsoft.gol.hcs.specialist.bean.response.FactorData;
import com.bsoft.gol.hcs.specialist.bean.response.InPatientInfoListResponse;
import com.bsoft.gol.hcs.specialist.bean.response.PatientSearchProcess;
import com.bsoft.gol.hcs.specialist.entity.PatientSearchRuleDetail;
import com.bsoft.gol.hcs.utils.CommonUtils;
import com.bsoft.gol.hcs.utils.Constants;
import com.bsoft.gol.hcs.utils.DateUtil;
import org.atag.dao.action.QoHibernateStatelessResultAction;
import org.atag.dao.model.SimplePageInfo;
import com.bsoft.gol.hcs.visitrecord.bean.qo.HospitalVisitsRecordListQo;
import com.bsoft.gol.hcs.visitrecord.bean.vo.HospitalVisitsRecordListVo;
import com.bsoft.gol.hcs.visitrecord.bean.vo.InpatientVisitRecordListVo;
import com.bsoft.gol.hcs.visitrecord.entity.VrInpatientVisitRecord;

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by ChenJij on 2020/9/4.
 */
public abstract class VrInpatientVisitRecordDAO extends HibernateSupportDelegateDAO<VrInpatientVisitRecord> {
    public VrInpatientVisitRecordDAO() {
        this.setKeyField("hospitalRecordId");
    }

    /**
     * @description: 更新满意度调查已完成数量
     * @author: chenJij@bsoft.com.cn
     * @date: 2020/10/9 13:25
     */
    @DAOMethod(sql = "update VrInpatientVisitRecord set finishNumber=finishNumber+1 where  " +
            "hospitalRecordId=:businessId")
    public abstract void updateFinishNumber(@DAOParam("businessId") String businessId);

    /**
     * 更新院后随访生成计划次数
     *
     * @param visitNo
     * @param organizationId
     * @return void
     * @throws
     * @author tongtp
     * @date 2022/6/7 19:30
     */
    @DAOMethod(sql = " update VrInpatientVisitRecord set fusAfterPlanTimes=fusAfterPlanTimes+1   where visitNo =:visitNo " +
            "and organizationId=:organizationId")
    public abstract void updateFusAfterPlanTimes(@DAOParam("visitNo") String visitNo,
                                                 @DAOParam("organizationId") String organizationId);

    /**
     * 根据日期删除住院记录
     * @param resultDate
     */
    @DAOMethod(sql = "delete from VrInpatientVisitRecord where discharge_time <:resultDate and deleteFlag!='1'")
    public abstract void deleteInpatientOverdueData(@DAOParam("resultDate") Date resultDate);

    /**
     * 根据日期查询记录列表
     * @param resultDate
     * @return
     */
    @DAOMethod(sql = "from VrInpatientVisitRecord where discharge_time <:resultDate and delete_flag !='1' ")
    public abstract List<VrInpatientVisitRecord> queryInpatientOverdueList(@DAOParam("resultDate") Date resultDate);
    /**
     * 更新删除标识
     */
    @DAOMethod(sql = "update VrInpatientVisitRecord set deleteFlag ='1' where  hospitalRecordId in(:recordIdList) ")
    public abstract void updateDeleteFlag(@DAOParam("recordIdList") List<String> recordIdList);

    @DAOMethod(sql = " from VrInpatientVisitRecord  where visitNo =:visitNo and organizationId=:organizationId")
    public abstract VrInpatientVisitRecord getByVisitNo(@DAOParam("visitNo") String visitNo, @DAOParam(
            "organizationId") String organizationId);

    /**
     * 查询同步数量
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @DAOMethod(sql = "select count(1) from VrInpatientVisitRecord  where  admissionTime>=:startTime and " +
            "admissionTime<=:endTime")
    public abstract Long getInpatientVisitByToday(@DAOParam("startTime") Date startTime,
                                                  @DAOParam("endTime") Date endTime);

    /**
     * 查询所有的病人id
     *
     * @return java.util.List<java.lang.String>
     * @throws
     * @author tongtp
     * @date 2022/6/14 15:15
     */
    public List<String> queryAllPatientId(final List<String> departmentIds) {
        HibernateStatelessResultAction<List<String>> action =
                new AbstractHibernateStatelessResultAction<List<String>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT DISTINCT patient_id AS patientId ");
                        sqlBuilder.append(" FROM vr_inpatient_visit_record ");
                        sqlBuilder.append(" WHERE patient_id is not null ");
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            sqlBuilder.append(" and department_id in (:departmentIds) ");
                        }
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            query.setParameterList("departmentIds", departmentIds);
                        }
                        List list = query.list();
                        List<String> voList;
                        if (CommonUtils.isNotEmpty(list)) {
                            voList = list;
                        } else {
                            voList = new ArrayList<>();
                        }
                        setResult(voList);
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据病人id查询最后一条住院记录
     *
     * @param patientId
     * @param departmentId
     * @return
     */

    public VrInpatientVisitRecord getByPatientIdAndLastOne(final String patientId, final String departmentId) {
        HibernateStatelessResultAction<VrInpatientVisitRecord> action =
                new AbstractHibernateStatelessResultAction<VrInpatientVisitRecord>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        List departmentIds = null;
                        if (CommonUtils.isNotNull(departmentId)) {
                            departmentIds = Arrays.asList(departmentId.split(","));
                        }
                        StringBuilder builder = new StringBuilder();
                        builder.append(" from VrInpatientVisitRecord  where  patientId =:patientId ");
                        builder.append(" and hospizationStatus != 0");
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            builder.append(" and departmentId in (:departmentIds) ");
                        }
                        builder.append(" order by dischargeTime desc");
                        Query query = ss.createQuery(builder.toString());
                        query.setParameter("patientId", patientId);
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            query.setParameterList("departmentIds", departmentIds);
                        }
//                query = query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
                        // 查询的条数
                        query.setMaxResults(1);
                        // 开始查询的位置
                        query.setFirstResult(0);
                        List<Map<String, Object>> dbList = query.list();
                        if (CommonUtils.isNotEmpty(dbList)) {
                            setResult(ConversionUtils.convert(dbList.get(0), VrInpatientVisitRecord.class));
                        } else {
                            setResult(null);
                        }
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据住院号码批量查询
     */
    @DAOMethod(sql = "from VrInpatientVisitRecord  where  inHospitalRecordCode in(:numberSet) ")
    public abstract List<VrInpatientVisitRecord> findByInHospitalRecordNumberSet(@DAOParam("numberSet") List<String> numberSet);

    @DAOMethod(sql = " from VrInpatientVisitRecord where visitNo =:visitNo and organizationId=:organizationId")
    public abstract VrInpatientVisitRecord getVrInpatientVisitRecord(@DAOParam("visitNo") String visitNo, @DAOParam("organizationId") String organizationId);

    @DAOMethod(sql = " from VrInpatientVisitRecord where inHospitalRecordCode =:inHospitalRecordCode and organizationId=:organizationId")
    public abstract VrInpatientVisitRecord getVrInpatientVisitRecordByCode(@DAOParam("inHospitalRecordCode") String inHospitalRecordCode, @DAOParam("organizationId") String organizationId);


    public SimplePageInfo<HospitalVisitsRecordListVo> queryOutpatientVisitRecordList(HospitalVisitsRecordListQo qo) {
        QoHibernateStatelessResultAction<HospitalVisitsRecordListVo, HospitalVisitsRecordListQo> action =
                new QoHibernateStatelessResultAction(true, qo, HospitalVisitsRecordListVo.class);
        action.setSql(" SELECT {{" +
                " '2' businessType, " +
                " hospital_record_id AS businessId, " +
                " organization_id AS organizationId, " +
                " patient_id AS patientId, " +
                " patient_name AS patientName, " +
                " patient_sex AS patientSex, " +
                " patient_age_text AS patientAge, " +
                " department_name AS departmentName, " +
                " survey_number AS surveyNumber, " +
                " finish_number AS finishNumber, " +
                " patient_medical_card_number AS patientMedicalCardNumber, " +
                " patient_medical_card_type AS patientMedicalCardType, " +
                " card_number AS cardNumber, " +
                " card_type AS cardType, " +
                " telephone, " +
                " admission_diagnosis AS inDiagnosisName, " +
                " discharge_diagnosis AS outDiagnosisName, " +
                " admission_time AS inHospitalDate, " +
                " discharge_time AS outHospitalDate  }}" +
                "FROM " +
                " vr_inpatient_visit_record where 1=1 ");
        action.addCondition(" and patient_name =:patientName ");
        action.addCondition(" and telephone =:telephone ");
        action.addCondition(" and patient_medical_card_number =:patientMedicalCardNumber ");
        action.addCondition(" and organization_id =:organizationId ");
        action.addCondition(" and department_id =:departmentId ");
        action.addCondition(" and attending_doctor_id =:doctorId ");

        if ("1".equals(qo.getDiagnosisServiceType())) {
            action.addCondition(" and admission_diagnosis =:diseasesName ");
        } else if ("2".equals(qo.getDiagnosisServiceType())) {
            action.addCondition(" and discharge_diagnosis =:diseasesName ");
        }

        if ("4".equals(qo.getDateType())) {
            action.addCondition(" and admission_time >=:beginDate ");
            action.addCondition(" and admission_time <:endDate ");
        } else if ("5".equals(qo.getDateType())) {
            action.addCondition(" and discharge_time >=:beginDate ");
            action.addCondition(" and discharge_time <:endDate ");
        }

        HibernateSessionTemplate.instance().execute(action);
        SimplePageInfo<HospitalVisitsRecordListVo> pageInfo = action.getSimpleResultPage();
        return pageInfo;
    }

    public SimplePageInfo<InpatientVisitRecordListVo> queryInpatientVisitRecordVos(HospitalVisitsRecordListQo qo) {
        QoHibernateStatelessResultAction<InpatientVisitRecordListVo, HospitalVisitsRecordListQo> action =
                new QoHibernateStatelessResultAction(true, qo, InpatientVisitRecordListVo.class);
        action.setSql(" SELECT {{" +
                " in_hospital_record_number AS inHospitalRecordNumber, " +
                " in_hospital_record_code AS inHospitalRecordCode, " +
                " medical_record_number AS medicalRecordNumber, " +
                " visit_no AS visitNo, " +
                " organization_id AS organizationId, " +
                " organization_name AS organizationName, " +
                " patient_id AS patientId, " +
                " patient_name AS patientName, " +
                " patient_sex AS patientSex, " +
                " patient_age_text AS patientAge, " +
                " department_name AS departmentName, " +
                " department_id AS departmentId, " +
                " bed_number AS bedNumber, " +
                " admission_diagnosis AS admissionDiagnosis, " +
                " discharge_diagnosis AS dischargeDiagnosis, " +
                " admission_time AS admissionTime, " +
                " discharge_time AS dischargeTime, " +
                " hospitalization_Times AS hospitalizationTimes, " +
                " attending_doctor_id AS attendingDoctorId, " +
                " attending_doctor_name AS attendingDoctorName " +
                " }}" +
                " FROM " +
                " vr_inpatient_visit_record where 1=1 ");
        action.addCondition(" and patient_name =:patientName ");
        action.addCondition(" and telephone =:telephone ");
        action.addCondition(" and patient_medical_card_number =:patientMedicalCardNumber ");
        action.addCondition(" and organization_id =:organizationId ");
        action.addCondition(" and department_id =:departmentId ");
        action.addCondition(" and attending_doctor_id =:doctorId ");
        action.addCondition(" and patient_id =:patientId ");
        action.addSql(" order by  admission_time desc");


        HibernateSessionTemplate.instance().execute(action);
        SimplePageInfo<InpatientVisitRecordListVo> pageInfo = action.getSimpleResultPage();
        return pageInfo;
    }

    public SimplePageInfo<InHospitalPatientResponse.InHospitalPatient> queryLocalInHospitalPatientList(InHospitalpatientListQueryRequest qo) {
        QoHibernateStatelessResultAction<VrInpatientVisitRecord, InHospitalpatientListQueryRequest> action = new QoHibernateStatelessResultAction(false, qo, VrInpatientVisitRecord.class);
        action.setSql(" SELECT {{" +
                " organization_id AS organizationId, " +
                " in_hospital_record_number AS inHospitalRecordNumber, " +
                " in_hospital_record_code AS inHospitalRecordCode, " +
                " patient_medical_card_number AS patientMedicalCardNumber, " +
                " card_number AS cardNumber, " +
                " patient_id AS patientId, " +
                " patient_name AS patientName, " +
                " bed_number AS bedNumber, " +
                " patient_sex AS patientSex, " +
                " patient_age AS patientAge, " +
                " patient_birthday AS patientBirthday, " +
                " address AS address, " +
                " admission_time AS admissionTime, " +
                " discharge_time AS dischargeTime, " +
                " patient_nature AS patientNature, " +
                " admission_diagnosis AS admissionDiagnosis, " +
                " discharge_diagnosis AS dischargeDiagnosis, " +
                " department_id AS departmentId, " +
                " department_name AS departmentName, " +
                " doctor_name AS doctorName }}" +
                " FROM " +
                " vr_inpatient_visit_record where 1=1 ");

        if (StringUtils.isNotEmpty(qo.getOrganizationId())) {
            action.addCondition(" and organization_id =:organizationId ");
        }
        if (StringUtils.isNotEmpty(qo.getDepartmentId())) {
            action.addCondition(" and department_id =:departmentId ");
        }
        if (StringUtils.isNotEmpty(qo.getDoctorId())) {
            action.addCondition(" and doctor_id =:doctorId ");
        }
        if (StringUtils.isNotEmpty(qo.getInHospitalStartDate())) {
            action.addCondition(" and admission_time >=:inHospitalStartDate ");
        }
        if (StringUtils.isNotEmpty(qo.getInHospitalEndDate())) {
            action.addCondition(" and admission_time <=:inHospitalEndDate ");
        }
        if (StringUtils.isNotEmpty(qo.getOutHospitalStartDate())) {
            action.addCondition(" and discharge_time >=:outHospitalStartDate ");
        }
        if (StringUtils.isNotEmpty(qo.getOutHospitalEndDate())) {
            action.addCondition(" and discharge_time <=:outHospitalEndDate ");
        }
        if (StringUtils.isNotEmpty(qo.getAdmissionDiagnosisCode())) {
            action.addCondition(" and hospital_record_id in( select business_id from vr_visit_diagnosis where business_type='2' and diagnosis_service_type='1' and diseases_code=:admissionDiagnosisCode ) ");
        }
        if (StringUtils.isNotEmpty(qo.getDischargeDiagnosisCode())) {
            action.addCondition(" and hospital_record_id in( select business_id from vr_visit_diagnosis where business_type='2' and diagnosis_service_type='2' and diseases_code=:dischargeDiagnosisCode ) ");
        }
        if (CommonUtils.isNotNull(qo.getQueryType()) && Constants.ONE == qo.getQueryType()) {
            action.addCondition(" and in_hospital_record_code =:query ");
        }
        if (CommonUtils.isNotNull(qo.getQueryType()) && Constants.THREE == qo.getQueryType()) {
            action.addCondition(" and bed_number =:query ");
        }
        if (CommonUtils.isNotNull(qo.getQueryType()) && Constants.TWO == qo.getQueryType()) {
            action.addSql(" and patient_name like '" + qo.getQuery() + "%' ");
        }

        action.addSql(" order by admission_time desc");


        HibernateSessionTemplate.instance().execute(action);
        List<VrInpatientVisitRecord> vrInpatientVisitRecords = action.getResultList();

        SimplePageInfo<InHospitalPatientResponse.InHospitalPatient> page = new SimplePageInfo();
        List<InHospitalPatientResponse.InHospitalPatient> inHospitalPatientList = Lists.newArrayList();
        page.setList(inHospitalPatientList);
        if (CommonUtils.isEmpty(vrInpatientVisitRecords)) {
            return page;
        }
        List<InHospitalPatientResponse.InHospitalPatient> screenInPatientInfoList = new ArrayList<>();
        for (VrInpatientVisitRecord vrInpatientVisitRecord : vrInpatientVisitRecords) {
            InHospitalPatientResponse.InHospitalPatient inHospitalPatient = new InHospitalPatientResponse.InHospitalPatient();
            BeanUtils.copyProperties(vrInpatientVisitRecord, inHospitalPatient);
            inHospitalPatient.setPrincipalDoctor(vrInpatientVisitRecord.getAttendingDoctorName());
            inHospitalPatientList.add(inHospitalPatient);
            if (CommonUtils.isNotEmpty(vrInpatientVisitRecord.getPatientAge())) {
                inHospitalPatient.setPatientAge(vrInpatientVisitRecord.getPatientAge());
            }
            if (CommonUtils.isNotEmpty(vrInpatientVisitRecord.getPatientBirthday())) {
                inHospitalPatient.setBirthday(DateUtil.formDate(vrInpatientVisitRecord.getPatientBirthday(), null));
            }
            if (CommonUtils.isNotEmpty(vrInpatientVisitRecord.getAdmissionTime())) {
                inHospitalPatient.setInDate(DateUtil.formDate(vrInpatientVisitRecord.getAdmissionTime(), null));
            }
            if (CommonUtils.isNotEmpty(vrInpatientVisitRecord.getDischargeTime())) {
                inHospitalPatient.setOutDate(DateUtil.formDate(vrInpatientVisitRecord.getDischargeTime(), null));
            }
            //勾选了隐藏入组患者
            if (qo.isHidePatient()) {
                BigInteger count = this.queryDiseaseNameCount(inHospitalPatient.getCardNumber(), inHospitalPatient.getOrganizationId(), qo.getDiseaseName());
                //如果该患者已经入组了该病种，则过滤该条记录
                if (count.intValue() > 0) {
                    continue;
                } else {
                    List<Map<String, String>> diseaseNameList = this.queryDiseaseNameByCardNumberAndOrgId(inHospitalPatient.getCardNumber(), inHospitalPatient.getOrganizationId());
                    if (CommonUtils.isNotEmpty(diseaseNameList)) {
                        String diseaseNames = "";
                        String diseaseIds = "";
                        for (Map diseaseNameMap : diseaseNameList) {
                            diseaseNames = diseaseNames + diseaseNameMap.get("diseaseName") + ",";
                            diseaseIds = diseaseIds + diseaseNameMap.get("chronicDiseaseId") + ",";
                        }
                        if (StringUtils.isNotEmpty(diseaseNames)) {
                            inHospitalPatient.setDiseaseName(diseaseNames.substring(0, diseaseNames.length() - 1));
                        }
                        if (CommonUtils.isNotEmpty(diseaseIds)) {
                            inHospitalPatient.setChronicDiseaseIds(diseaseIds.substring(0, diseaseIds.length() - 1));
                        }
                    }
                    screenInPatientInfoList.add(inHospitalPatient);
                }
                page.setTotal(screenInPatientInfoList.size());
            } else {
                List<Map<String, String>> diseaseNameList = this.queryDiseaseNameByCardNumberAndOrgId(inHospitalPatient.getCardNumber(), inHospitalPatient.getOrganizationId());
                if (CommonUtils.isNotEmpty(diseaseNameList)) {
                    String diseaseNames = "";
                    String diseaseIds = "";
                    for (Map diseaseNameMap : diseaseNameList) {
                        diseaseNames = diseaseNames + diseaseNameMap.get("diseaseName") + ",";
                        diseaseIds = diseaseIds + diseaseNameMap.get("chronicDiseaseId") + ",";
                    }
                    if (StringUtils.isNotEmpty(diseaseNames)) {
                        inHospitalPatient.setDiseaseName(diseaseNames.substring(0, diseaseNames.length() - 1));
                    }
                    if (CommonUtils.isNotEmpty(diseaseIds)) {
                        inHospitalPatient.setChronicDiseaseIds(diseaseIds.substring(0, diseaseIds.length() - 1));
                    }
                }
                screenInPatientInfoList.add(inHospitalPatient);
            }
            page.setTotal(screenInPatientInfoList.size());
        }
        //处理分页参数
        int pageNo = qo.getPageNo();
        int pageSize = qo.getPageSize();
        List<InHospitalPatientResponse.InHospitalPatient> patientInfoList = screenInPatientInfoList.stream().skip((pageNo - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        page.setList(patientInfoList);
        return page;
    }

    /**
     * 根据病人idCard获取住院记录
     *
     * @param qo
     * @return
     */
    public List<InPatientInfoListResponse> queryInPatientInfoListByIdCard(GroupChronicRecordQo qo) {
        HibernateStatelessResultAction<List<InPatientInfoListResponse>> action = new AbstractHibernateStatelessResultAction<List<InPatientInfoListResponse>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT hospital_record_id as inPatientInfoId,admission_time as beAdmissionTime,discharge_time as dischargeTime from vr_inpatient_visit_record WHERE card_number =:idCard ");
                sqlBuilder.append(" and discharge_time >=:beginTime and discharge_time <=:endTime order by discharge_time ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("idCard", qo.getIdCard());
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("beginTime", qo.getBeginTime()+" 00:00:00");
                }
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("endTime", qo.getEndTime()+" 23:59:59");
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<InPatientInfoListResponse> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, InPatientInfoListResponse.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询慢病名称
     *
     * @param cardNumber     身份证号
     * @param organizationId 机构编码
     * @return 慢病名称
     */
    public List<Map<String, String>> queryDiseaseNameByCardNumberAndOrgId(final String cardNumber, final String organizationId) {
        HibernateStatelessResultAction<List<Map<String, String>>> action =
                new AbstractHibernateStatelessResultAction<List<Map<String, String>>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT chronic_disease_id as chronicDiseaseId,chronic_disease_name as diseaseName from fus_team_chronic_group_record " +
                                " WHERE card_number =:cardNumber and organization_id =:organizationId and apply_status = '1' ");
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setParameter("cardNumber", cardNumber);
                        query.setParameter("organizationId", organizationId);
                        query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                        List<Map<String, String>> list = query.list();
                        if (CommonUtils.isNotEmpty(list)) {
                            setResult(list);
                        }
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询该患者是否入组了该病种
     *
     * @param cardNumber
     * @param organizationId
     * @return
     */
    public BigInteger queryDiseaseNameCount(final String cardNumber, final String organizationId, final String diseaseName) {
        HibernateStatelessResultAction<BigInteger> action =
                new AbstractHibernateStatelessResultAction<BigInteger>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT count(1) as count from fus_team_chronic_group_record " +
                                " WHERE card_number =:cardNumber and organization_id =:organizationId ");
                        if (CommonUtils.isNotEmpty(diseaseName)) {
                            sqlBuilder.append(" and chronic_disease_name =:diseaseName ");
                        }
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setParameter("cardNumber", cardNumber);
                        query.setParameter("organizationId", organizationId);
                        if (CommonUtils.isNotEmpty(diseaseName)) {
                            query.setParameter("diseaseName", diseaseName);
                        }
                        List list = query.list();
                        if (list.size() == 1) {
                            Object o = list.get(0);
                            BigInteger count = (BigInteger) o;
                            setResult(count);
                        }
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询门诊患者记录表内接诊医生
     *
     * @param organizationId 机构编码
     * @return 医生
     */
    public List<Map<String, String>> inPatientDoctorList(final String organizationId) {
        HibernateStatelessResultAction<List<Map<String, String>>> action = new AbstractHibernateStatelessResultAction<List<Map<String, String>>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT attending_doctor_id as doctorId,attending_doctor_name as doctorName from vr_inpatient_visit_record WHERE organization_id =:organizationId group by attending_doctor_id,attending_doctor_name ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("organizationId", organizationId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    setResult(list);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * @description: 根据诊断编码、诊断时间、病人id集合查询诊断记录集合
     * @param: factorIdList 诊断编码集合
     * @param: diagnosisTime
     * @param: diagnosisServiceType 业务诊断类型：1入院诊断、2出院诊断、3门诊诊断、5其他诊断
     * @param: patientIdList
     * @return: java.util.List<specialist.bean.response.FactorData>
     */
    public List<FactorData> executeFactorForInpatient(List<String> factorIdList, Date startTime, Date endTime, String diagnosisServiceType, List<String> patientIdList,Byte isLoopExecute,Long routeDetailId, String followType) {
        HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,organizationId,hospitalRecordId,doctorId ,doctorName,dischargeTime,dataSource from (");
                sqlBuilder.append("SELECT patient_id as patientId,organization_id organizationId,hospital_record_id hospitalRecordId, ");
                sqlBuilder.append(" doctor_id doctorId,doctor_name doctorName,discharge_time dischargeTime,'1' dataSource ");
                sqlBuilder.append("  FROM `vr_inpatient_visit_record`  ");
                sqlBuilder.append(" WHERE doctor_id in(:doctorIdList)  ");
                if (null != startTime) {
                    sqlBuilder.append("  and  discharge_time>:startTime ");
                }
                if (null != endTime) {
                    sqlBuilder.append("  and  discharge_time<:endTime ");
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    sqlBuilder.append(" and patient_id in(:patientIdList)");
                }
                sqlBuilder.append(") AS  m ");
                //循环执行机制 0 不执行 1 执行
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f.route_detail_id = :routeDetailId AND f.hospital_record_id = m.hospitalRecordId WHERE f.id IS NULL  ");
                }
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameterList("doctorIdList", factorIdList);
                if (null != startTime) {
                    query.setParameter("startTime", startTime);
                }
                if (null != endTime) {
                    query.setParameter("endTime", endTime);
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    query.setParameterList("patientIdList", patientIdList);
                }
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    query.setParameter("routeDetailId", routeDetailId);
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<FactorData> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, FactorData.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public List<FactorData> executeFactorForInpatientStatus(List<String> deptIdList, Date startTime, Date endTime, List<String> patientIdList, boolean isInHospital,Byte isLoopExecute,Long routeDetailId, String followType) {
        HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,organizationId,hospitalRecordId,dataSource from (");
                sqlBuilder.append("SELECT patient_id as patientId,organization_id organizationId,hospital_record_id hospitalRecordId, '1' as dataSource, ");
                sqlBuilder.append(" discharge_time dischargeTime FROM `vr_inpatient_visit_record`");
                sqlBuilder.append(" WHERE 1=1 ");
                if(isInHospital){
                    sqlBuilder.append(" hospization_status = 0");
                }
                if (CommonUtils.isNotEmpty(startTime)) {
                    sqlBuilder.append(" and admission_time >:startTime  ");
                }
                if (CommonUtils.isNotEmpty(endTime)) {
                    sqlBuilder.append(" and admission_time <:endTime  ");
                }
                if (CommonUtils.isNotEmpty(deptIdList)) {
                    sqlBuilder.append(" and attending_doctor_id in(:deptIdList) ");
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    sqlBuilder.append(" and patient_id in(:patientIdList)");
                }
                sqlBuilder.append(") AS  m ");
                //循环执行机制 0 不执行 1 执行
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f.route_detail_id = :routeDetailId AND f.hospital_record_id = m.hospitalRecordId WHERE f.id IS NULL  ");
                }
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                if (CommonUtils.isNotEmpty(startTime)) {
                    query.setParameter("startTime", startTime);
                }
                if (CommonUtils.isNotEmpty(endTime)) {
                    query.setParameter("endTime", endTime);
                }
                if (CommonUtils.isNotEmpty(deptIdList)) {
                    query.setParameterList("deptIdList", deptIdList);
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    query.setParameterList("patientIdList", patientIdList);
                }
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    query.setParameter("routeDetailId", routeDetailId);
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<FactorData> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, FactorData.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public List<FactorData> executeFactorForInpatientStatus(List<String> deptIdList, Date endTime, List<String> patientIdList,Byte isLoopExecute,Long routeDetailId, String followType) {
        HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,organizationId,hospitalRecordId,dataSource from (");
                sqlBuilder.append("SELECT patient_id as patientId,organization_id organizationId,hospital_record_id hospitalRecordId, '1' as dataSource, ");
                sqlBuilder.append(" discharge_time dischargeTime FROM `vr_inpatient_visit_record`");
                sqlBuilder.append(" WHERE 1=1 and hospization_status > 0 ");
                if (CommonUtils.isNotEmpty(endTime)) {
                    sqlBuilder.append(" and discharge_time <:endTime  ");
                }
                if (CommonUtils.isNotEmpty(deptIdList)) {
                    sqlBuilder.append(" and attending_doctor_id in(:deptIdList) ");
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    sqlBuilder.append(" and patient_id in(:patientIdList)");
                }
                sqlBuilder.append(") AS  m ");
                //循环执行机制 0 不执行 1 执行
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f.route_detail_id = :routeDetailId AND f.hospital_record_id = m.hospitalRecordId WHERE f.id IS NULL  ");
                }
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                if (CommonUtils.isNotEmpty(endTime)) {
                    query.setParameter("endTime", endTime);
                }
                if (CommonUtils.isNotEmpty(deptIdList)) {
                    query.setParameterList("deptIdList", deptIdList);
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    query.setParameterList("patientIdList", patientIdList);
                }
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    query.setParameter("routeDetailId", routeDetailId);
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<FactorData> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, FactorData.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public Integer executeFactorForOutpatientStatus(String patientId, Date startTime) {
        HibernateStatelessResultAction<Integer> action =
                new AbstractHibernateStatelessResultAction<Integer>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT   (CASE WHEN a.count1 > 0 THEN 1 ELSE ");
                        sqlBuilder.append(" (SELECT COUNT(1)  FROM  fus_answer_in_hospital_info  WHERE patient_id = :patientId   AND discharge_time > :startTime)   END)  as COUNT");
                        sqlBuilder.append("  FROM (SELECT   COUNT(1) count1 FROM vr_inpatient_visit_record WHERE patient_Id = :patientId  AND (hospization_status=0 or discharge_time > :startTime )) a  ");
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setParameter("patientId", patientId);
                        query.setParameter("startTime", startTime);
                        List list = query.list();
                        if (list.size() == 1) {
                            Object o = list.get(0);
                            Integer count = (Integer) o;
                            setResult(count);
                        }
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
    public List<PatientSearchProcess> queryInOrOutHospitalDiagnosisRecord(final PatientSearchRuleDetail patientSearchRuleDetail, final Date recordStartTime, final Date recordEndTime) {
        HibernateStatelessResultAction<List<PatientSearchProcess>> action =
                new AbstractHibernateStatelessResultAction<List<PatientSearchProcess>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT " +
                                "vr.patient_id as patientId, " +
                                "vr.patient_name AS patientName, " +
                                "vr.organization_id as organizationId, " +
                                "vr.organization_name as organizationName, " +
                                "vr.patient_sex AS patientSex, " +
                                "vr.card_type AS cardType, " +
                                "vr.card_number AS cardNumber, " +
                                "vr.patient_age as patientAge, " +
                                "vr.in_hospital_record_code AS patientNumber," +
                                "( SELECT GROUP_CONCAT( distinct f.chronic_disease_id ) FROM fus_team_chronic_group_record f WHERE vr.card_number = f.card_number and f.apply_status = '1') AS chronicDiseaseIds,"+
                                "( SELECT GROUP_CONCAT( distinct f.chronic_disease_name ) FROM fus_team_chronic_group_record f WHERE vr.card_number = f.card_number and f.apply_status = '1') AS chronicDiseaseName " +
                                "FROM " +
                                "vr_inpatient_visit_record vr where 1=1 and ( vr.delete_flag !='1' or vr.delete_flag is null )  ");
                        if (RuleConditionTypeEnum.IN_HOSPITAL_DIAGNOSIS.getType() == patientSearchRuleDetail.getRuleConditionType()){
                            sqlBuilder.append(" and vr.admission_diagnosis in (:diagnosisList) ");
                        }
                        if (RuleConditionTypeEnum.OUT_HOSPITAL_DIAGNOSIS.getType() == patientSearchRuleDetail.getRuleConditionType()){
                            sqlBuilder.append(" and vr.discharge_diagnosis in (:diagnosisList) ");
                        }
                        if (CommonUtils.isNotEmpty(recordStartTime) && CommonUtils.isNotEmpty(recordEndTime)) {
                            sqlBuilder.append(" and vr.admission_time  >=:recordStartTime and vr.admission_time <=:recordEndTime");
                        }
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setParameterList("diagnosisList", patientSearchRuleDetail.getDiagnosisList());
                        if (CommonUtils.isNotEmpty(recordStartTime) && CommonUtils.isNotEmpty(recordEndTime)) {
                            query.setParameter("recordStartTime", DateUtil.dateFormate(recordStartTime,"yyyy-MM-dd"));
                            query.setParameter("recordEndTime", DateUtil.dateFormate(recordEndTime,"yyyy-MM-dd")+" 23:59:59");
                        }
                        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
                        List<Map> list = query.list();
                        List<PatientSearchProcess> voList = new ArrayList<>();
                        if (CommonUtils.isNotEmpty(list)) {
                            for (Map map : list) {
                                voList.add(ConversionUtils.convert(map, PatientSearchProcess.class));
                            }
                        } else {
                            voList = new ArrayList<>();
                        }
                        setResult(voList);
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
}